<template>
  <div>
    <el-form :model="formConfig" size="mini" label-position="left" label-width="120px"
             class="setting-form" @submit.native.prevent>
      <el-collapse v-model="formActiveCollapseNames" class="setting-collapse">
        <el-collapse-item name="1" :title="i18nt('designer.setting.basicSetting')">
          <el-form-item :label="i18nt('designer.setting.formSize')">
            <el-select v-model="formConfig.size">
              <el-option v-for="item in formSizes" :key="item.value" :label="item.label"
                         :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelPosition')">
            <el-radio-group v-model="formConfig.labelPosition" class="radio-group-custom">
              <el-radio-button label="left">{{ i18nt('designer.setting.leftPosition') }}</el-radio-button>
              <el-radio-button label="top">{{ i18nt('designer.setting.topPosition') }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelAlign')">
            <el-radio-group v-model="formConfig.labelAlign" class="radio-group-custom">
              <el-radio-button label="label-left-align">{{ i18nt('designer.setting.leftAlign') }}</el-radio-button>
              <el-radio-button label="label-center-align">{{ i18nt('designer.setting.centerAlign') }}</el-radio-button>
              <el-radio-button label="label-right-align">{{ i18nt('designer.setting.rightAlign') }}</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.labelWidth')">
            <el-input-number v-model="formConfig.labelWidth" :min="0" style="width: 100%"></el-input-number>
          </el-form-item>
          <el-form-item :label="i18nt('designer.setting.formCss')">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormCss">
              {{ i18nt('designer.setting.addCss') }}
            </el-button>
          </el-form-item>
          <!-- -->
          <el-form-item :label="i18nt('designer.setting.customClass')">
            <el-select v-model="formConfig.customClass" multiple filterable allow-create
                       default-first-option>
              <el-option v-for="(item, idx) in cssClassList" :key="idx" :label="item" :value="item"></el-option>
            </el-select>
          </el-form-item>
          <!-- -->
<!--          <el-form-item :label="i18nt('designer.setting.globalFunctions')">-->
<!--            <el-button type="info" icon="el-icon-edit" plain round @click="editGlobalFunctions">-->
<!--              {{ i18nt('designer.setting.addEventHandler') }}-->
<!--            </el-button>-->
<!--          </el-form-item>-->
          <!--          <el-form-item label-width="0">-->
          <!--            <el-divider class="custom-divider">{{i18nt('designer.setting.formSFCSetting')}}</el-divider>-->
          <!--          </el-form-item>-->
          <!--          <el-form-item :label="i18nt('designer.setting.formModelName')">-->
          <!--            <el-input type="text" v-model="formConfig.modelName"></el-input>-->
          <!--          </el-form-item>-->
          <!--          <el-form-item :label="i18nt('designer.setting.formRefName')">-->
          <!--            <el-input type="text" v-model="formConfig.refName"></el-input>-->
          <!--          </el-form-item>-->
          <!--          <el-form-item :label="i18nt('designer.setting.formRulesName')">-->
          <!--            <el-input type="text" v-model="formConfig.rulesName"></el-input>-->
          <!--          </el-form-item>-->
        </el-collapse-item>

        <el-collapse-item v-if="showEventCollapse()" name="2" :title="i18nt('designer.setting.eventSetting')">
          <el-form-item label="onFormCreated" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormCreated')">
              {{ i18nt('designer.setting.addEventHandler') }}
            </el-button>
          </el-form-item>
          <el-form-item label="onFormMounted" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormMounted')">
              {{ i18nt('designer.setting.addEventHandler') }}
            </el-button>
          </el-form-item>
          <!-- -->
          <el-form-item label="onFormDataChange" label-width="150px">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormDataChange')">
              {{ i18nt('designer.setting.addEventHandler') }}
            </el-button>
          </el-form-item>
          <!-- -->
          <!--
          <el-form-item label="onFormValidate">
            <el-button type="info" icon="el-icon-edit" plain round @click="editFormEventHandler('onFormValidate')">
              {{i18nt('designer.setting.addEventHandler')}}</el-button>
          </el-form-item>
          -->
        </el-collapse-item>
      </el-collapse>
    </el-form>

    <el-dialog :title="i18nt('designer.setting.editFormEventHandler')" :visible.sync="showFormEventDialogFlag"
               v-if="showFormEventDialogFlag" :show-close="true" class="small-padding-dialog max-height"
               :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
               :append-to-body="true">
      <event-editor v-model="formEventHandlerCode" :condition-elements="elements" :designer="designer"
                    :eventConfig="eventConfig"/>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showFormEventDialogFlag = false">
          {{ i18nt('designer.hint.cancel') }}
        </el-button>
        <el-button type="primary" @click="saveFormEventHandler">
          {{ i18nt('designer.hint.confirm') }}
        </el-button>
      </div>
    </el-dialog>

    <el-dialog :title="i18nt('designer.setting.formCss')" :visible.sync="showEditFormCssDialogFlag"
               v-if="showEditFormCssDialogFlag" :show-close="true" class="small-padding-dialog max-height"
               :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
               :append-to-body="true">
      <code-editor :mode="'css'" :readonly="false" v-model="formCssCode"></code-editor>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showEditFormCssDialogFlag = false">
          {{ i18nt('designer.hint.cancel') }}
        </el-button>
        <el-button type="primary" @click="saveFormCss">
          {{ i18nt('designer.hint.confirm') }}
        </el-button>
      </div>
    </el-dialog>

    <el-dialog :title="i18nt('designer.setting.globalFunctions')" :visible.sync="showEditFunctionsDialogFlag"
               v-if="showEditFunctionsDialogFlag" :show-close="true" class="small-padding-dialog max-height"
               :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true"
               :append-to-body="true">
      <event-editor v-model="functionsCode" :condition-elements="elements" :designer="designer"
                    :eventConfig="eventConfig"/>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showEditFunctionsDialogFlag = false">
          {{ i18nt('designer.hint.cancel') }}
        </el-button>
        <el-button type="primary" @click="saveGlobalFunctions">
          {{ i18nt('designer.hint.confirm') }}
        </el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import i18n from "@/components/v-form-design/utils/i18n"
import CodeEditor from '@/components/v-form-design/code-editor'
import {deepClone, insertCustomCssToHead, insertGlobalFunctionsToHtml} from "@/components/v-form-design/utils/util"
import EventEditor from "@/components/v-form-design/form-designer/event-editor";
import {ColumnsExcludeType} from "@/config/column";

export default {
  name: "form-setting",
  mixins: [i18n],
  components: {
    EventEditor,
    CodeEditor,
  },
  props: {
    designer: Object,
    formConfig: Object,
  },
  inject: ['getDesignerConfig'],
  data() {
    return {
      designerConfig: this.getDesignerConfig(),

      formActiveCollapseNames: ['1', '2'],

      formSizes: [
        {label: 'default', value: ''},
        {label: 'large', value: 'large'},
        {label: 'medium', value: 'medium'},
        {label: 'small', value: 'small'},
        {label: 'mini', value: 'mini'},
      ],

      showEditFormCssDialogFlag: false,
      formCssCode: '',
      cssClassList: [],

      showEditFunctionsDialogFlag: false,
      functionsCode: '',

      showFormEventDialogFlag: false,
      formEventHandlerCode: '',
      elements: [],
      eventConfig: {},
      curEventName: '',

      eventParamsMap: {
        'onFormCreated': 'onFormCreated() {',
        'onFormMounted': 'onFormMounted() {',
        'onFormDataChange': 'onFormDataChange(fieldName, newValue, oldValue, formModel, subFormName, subFormRowIndex) {',
        //'onFormValidate':     'onFormValidate() {',
      },

    }
  },
  created() {
    //导入表单JSON后需要重新加载自定义CSS样式！！！
    this.designer.handleEvent('form-json-imported', () => {
      this.formCssCode = this.formConfig.cssCode
      insertCustomCssToHead(this.formCssCode)
      this.extractCssClass()
      this.designer.emitEvent('form-css-updated', deepClone(this.cssClassList))
    })
  },
  mounted() {
    /* SettingPanel和FormWidget为兄弟组件, 在FormWidget加载formConfig时，
       此处SettingPanel可能无法获取到formConfig.cssCode, 故加个延时函数！ */
    setTimeout(() => {
      this.formCssCode = this.formConfig.cssCode
      insertCustomCssToHead(this.formCssCode)
      this.extractCssClass()
      this.designer.emitEvent('form-css-updated', deepClone(this.cssClassList))
    }, 1200)
  },
  methods: {
    showEventCollapse() {
      if (this.designerConfig['eventCollapse'] === undefined) {
        return true
      }

      return !!this.designerConfig['eventCollapse']
    },

    editFormCss() {
      this.formCssCode = this.designer.formConfig.cssCode
      this.showEditFormCssDialogFlag = true
    },

    extractCssClass() {
      let regExp = /\..*{/g
      let result = this.formCssCode.match(regExp)
      let cssNameArray = []

      if (!!result && result.length > 0) {
        result.forEach((rItem) => {
          let classArray = rItem.split(',')  //切分逗号分割的多个class
          if (classArray.length > 0) {
            classArray.forEach((cItem) => {
              let caItem = cItem.trim()
              if (caItem.indexOf('.', 1) !== -1) {  //查找第二个.位置
                let newClass = caItem.substring(caItem.indexOf('.') + 1, caItem.indexOf('.', 1))  //仅截取第一、二个.号之间的class
                if (!!newClass) {
                  cssNameArray.push(newClass.trim())
                }
              } else if (caItem.indexOf(' ') !== -1) {  //查找第一个空格位置
                let newClass = caItem.substring(caItem.indexOf('.') + 1, caItem.indexOf(' '))  //仅截取第一、二个.号之间的class
                if (!!newClass) {
                  cssNameArray.push(newClass.trim())
                }
              } else {
                if (caItem.indexOf('{') !== -1) {  //查找第一个{位置
                  let newClass = caItem.substring(caItem.indexOf('.') + 1, caItem.indexOf('{'))
                  cssNameArray.push(newClass.trim())
                } else {
                  let newClass = caItem.substring(caItem.indexOf('.') + 1)
                  cssNameArray.push(newClass.trim())
                }
              }
            })
          }
        })
      }

      //this.cssClassList.length = 0
      this.cssClassList.splice(0, this.cssClassList.length)  //清除数组必须用splice，length=0不会响应式更新！！
      this.cssClassList = Array.from(new Set(cssNameArray))  //数组去重
    },

    saveFormCss() {
      this.extractCssClass()
      this.designer.formConfig.cssCode = this.formCssCode
      insertCustomCssToHead(this.formCssCode)
      this.showEditFormCssDialogFlag = false

      this.designer.emitEvent('form-css-updated', deepClone(this.cssClassList))
    },

    editGlobalFunctions() {
      this.functionsCode = _.cloneDeep(this.designer.formConfig.functions || {events: []})
      this.elements = _.map(this.designer.formWidget.widgetRefList, (fieldComponent, value) => {
        return {
          value,
          label: fieldComponent.$options.propsData.field.options.label,
          originalData: _.cloneDeep(fieldComponent.$options.propsData.field)
        }
      }).filter((item) => {
        return !ColumnsExcludeType.includes(item.originalData.type)
      })
      this.showEditFunctionsDialogFlag = true
    },

    saveGlobalFunctions() {
      this.designer.formConfig.functions = this.functionsCode
      insertGlobalFunctionsToHtml(this.functionsCode)
      this.showEditFunctionsDialogFlag = false
    },

    editFormEventHandler(eventName) {
      this.curEventName = eventName
      this.formEventHandlerCode = _.cloneDeep(this.formConfig[eventName] || {events: []})
      this.elements = _.map(this.designer.formWidget.widgetRefList, (fieldComponent, value) => {
        return {
          value,
          label: fieldComponent.$options.propsData.field.options.label,
          originalData: _.cloneDeep(fieldComponent.$options.propsData.field)
        }
      }).filter((item) => {
        return !ColumnsExcludeType.includes(item.originalData.type)
      })
      this.showFormEventDialogFlag = true
    },

    saveFormEventHandler() {
      this.formConfig[this.curEventName] = this.formEventHandlerCode
      this.showFormEventDialogFlag = false
    },

  }
}
</script>

<style lang="scss" scoped>
.setting-form {
  ::v-deep .el-form-item__label {
    font-size: 13px;
    //text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
  }

  ::v-deep .el-form-item--mini.el-form-item {
    margin-bottom: 6px;
  }

  .radio-group-custom {
    ::v-deep .el-radio-button__inner {
      padding-left: 12px;
      padding-right: 12px;
    }
  }

  .custom-divider.el-divider--horizontal {
    margin: 10px 0;
  }
}

.setting-collapse {
  ::v-deep .el-collapse-item__content {
    padding-bottom: 6px;
  }

  ::v-deep .el-collapse-item__header {
    font-style: italic;
    font-weight: bold;
  }
}

.small-padding-dialog {
  ::v-deep .el-dialog__body {
    padding: 6px 15px 12px 15px;
  }
}

</style>
